import functools
import json
import time

from flask import Blueprint, redirect
from application.models.users.user import *
import random, re, redis, requests
from flask import jsonify, request, make_response, current_app
from captcha.image import ImageCaptcha  # 验证生成类
from werkzeug.security import generate_password_hash, check_password_hash
from tools.captcha.captcha import captcha
from tools.myredis import r
from tools.comm import sendMsg, get_ali_object
from tools.myjwt import mjwt

user_blue = Blueprint("userblue", __name__)


# 权限认证
# def islogin(func):
#     @functools.wraps(func)
#     def wrapper():
#         # func()
#         #权限验证判断 如果有问题返回
#         return func
#     return wrapper
def islogin(type):
    def pemistion(func):
        def wrapper():
            func()
            if type == 1:
                return redirect('http://www.baidu.com')
            else:
                return redirect('http://www.jd.com')

        return wrapper

    return pemistion


# # 测试
@user_blue.route('/test')
def test():
    pass


# 获取验证图片
@user_blue.route("/getcode")
# @islogin(2)
def regcode():
    # print('getcode')
    # 生成图片验证码 text文字,image图片流
    name, text, image = captcha.generate_captcha()
    # 从页面获取uuid作为redis key
    uuid = str(request.args.get('uuid'))
    # 存入redis
    r.str_add(uuid, str(text), 60)
    # 以流的方式生成图片验证码
    res = make_response(image)
    res.headers['Content-Type'] = 'image/jpg'
    return res


# 发送短信验证码
@user_blue.route('/sendSmsCode', methods=['POST'])
def send_sms():
    data = request.data
    print(data)
    if data:
        data = json.loads(data)
        # 获取3个参数
        uuid = data.get('uuid')
        piccode = data.get('piccode')
        mobile = data.get('mobile')
        # 通过uuid查询redis
        value = r.str_get(uuid)
        if value:
            # 俩个验证码对比,如果成功调用短信平台发短信
            if piccode.lower() == value.lower():
                # 验证1分钟内只能发一次
                mcode = r.str_get(mobile)
                if mcode:
                    return jsonify({'code': 10012, 'mes': '一分钟内不能重复发'})
                # 生成5位随机数
                scode = random.randint(10000, 99999)
                # 调用短信平台
                flag = sendMsg(mobile, scode)
                if flag == True:
                    # print("验证码》》》》》",scode)
                    # 存入redis
                    r.str_add(mobile, scode, 60)
                    # 删除图片验证码
                    r.del_str(uuid)
                    # 返回结果
                    return jsonify({'code': 10013, 'mes': '发送验证码失效'})
                else:
                    return jsonify({'code': 200, 'mes': f'发送成功,验证码为{scode}'})
            else:
                return jsonify({'code': 10011, 'mes': '图片验证错误'})
            # 失败返回错误信息
        else:
            return jsonify({'code': 10010, 'mes': '图片验证不存在'})


# 注册登录
@user_blue.route('/login', methods=['POST'])
def login():
    # 获取参数,手机号m验证码
    data = request.data
    if data:
        data = json.loads(data)
        # 获取参数
        # 获取2个参数
        mcode = data.get('mcode')
        mobile = data.get('mobile')
        # 根据手机号去redis获取验证码

        code = r.str_get(mobile)
        # 判断是否存在
        if code:
            # 验证码是否相同
            if str(code) == str(mcode):

                # 如果相同查询数据库user表
                # 如果不相同返回错误
                # 如果存在返回用户信息
                user = User.query.filter(User.mobile == mobile).first()
                if user:
                    # 删除redis中的验证码
                    r.del_str(mobile)
                else:
                    u = User(mobile=mobile, nikename=mobile)
                    db.session.add(u)
                    db.session.commit()
                    print("注册成功")
                    user = User.query.filter(User.mobile == mobile).first()
                # 用户信息生成JWT  token
                token = mjwt.encode(data={'data': {'uid': user.id, 'exp': int(time.time())}})

                return jsonify({'code': 200, 'token': token, 'userid': user.id})
                # 返回给页面
            else:
                return jsonify({'code': 10021, 'mes': '验证码错误'})

        else:
            return jsonify({'code': 10020, 'mes': '登录成功'})




# 获取weibo地址
@user_blue.route('/getwxurl')
def getwburl():
    client_id = '3674019597'
    redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
    url = "https://api.weibo.com/oauth2/authorize?client_id=%s&response_type=code&redirect_uri=%s" % (
        client_id, redirect_uri)
    return jsonify({'code': 200, 'url': url})


# weibo回调接口
@user_blue.route('/weiboCallback/')
def weiboCallback():
    # 获取code
    code = request.args.get('code')
    # 向access-token接口发起post请求
    data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
            "grant_type": "authorization_code",
            'redirect_uri': "http://127.0.0.1:8000/user/weiboCallback/", 'code': code}
    res = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
    # 解析参数，tolken，uid
    mes = json.loads(res.text)

    token = mes['access_token']
    uid = mes['uid']

    # 查询三方登录中uid是否存在，如果存在，查询用户表，用用户信息生成token跳转到vue页面
    # sf = SfLogin.query.filter(SfLogin.uid == uid).first()
    # if sf:
    #     user = User.query.filter(User.id == sf.userid).first()
    #     data={'data':{"userid":user[0],"exp":int(time.time())}}
    #     token = mjwt.jwt_encode(data)
    #     return redirect('http://localhost:8080/#/upateToken?userid='+str(user[0])+"&token="+token)

    sql = "select user.id from user inner join sf_login on user.id=sf_login.userid where sf_login.uid='%s'" % (uid)
    user = db.session.execute(sql)
    # orm查询
    # 判断是否查询到
    if user:
        for i in user:
            data = {'data': {"userid": i[0], "exp": int(time.time())}}
            token = mjwt.jwt_encode(data)
            return redirect('http://localhost:8080/#/upateToken?userid=' + str(i[0]) + "&token=" + token)
    # 不存在跳转到vue绑定页面，token uid传递过去
    return redirect('http://localhost:8080/#/bindMobile?uid=' + uid + "&token=" + token)


# 绑定手机号
@user_blue.route('/bindMobile', methods=['POST'])
def bindMobile():
    data = json.loads(request.data)
    mobile = data.get('mobile')
    uid = data.get('uuid')
    token = data.get('token')
    # 先查询用户表, 如果手机号存在，获取userid,写入三方登录,生成token返回
    user = User.query.filter(User.mobile == mobile).first()
    if not user:
        # 添加用户
        u = User(mobile=mobile)
        db.session.add(u)
        db.session.commit()
        # 获取用户信息
        user = User.query.filter(User.mobile == mobile).first()

    sfuser = SfLogin(userid=user.id, webfrom='wb', uid=uid, token=token)
    db.session.add(sfuser)
    db.session.commit()

    # 如果不存在,写入user表,再写入三
    # 获取userid,写入三方登录表,生成token返回
    data = {'data': user.id, "exp": int(time.time())}
    token = str(mjwt.jwt_encode(data))
    return jsonify({'userid': str(user.id), 'token': token})


@user_blue.route('/cart', methods=['POST'])
def cart():
    pass


# 购买VIP订单
@user_blue.route("/buy", methods=['POST'])
def buy():
    # 获取参数
    data = json.loads(request.data)
    userid = data['userid']
    year = data['year']
    money = 200
    # 生成订单
    # userid = db.Column(db.Integer, db.ForeignKey( 'user.id'))# year = db.Column(db.Integer,default=1)
    # money = db.Column(db.Float)
    # discount = db.Column(db.Float)
    # active_money = db.Column(db.Float)
    # status = dbColumn(db.Integer,default=1)VipRecord(userid)
    tmoney = money * int(year)
    order_no = str(int(time.time())) + str(userid) + str(random.randint(100, 999))
    viprecord = VipRecord(order_no=order_no, userid=userid, year=year, money=tmoney, active_money=tmoney, status=1)
    db.session.add(viprecord)
    db.session.commit()

    pay = get_ali_object()
    # 生成支付的url
    query_params = pay.direct_pay(
        subject="test",  # 商品简单描述
        out_trade_no=str(order_no),  # 用户购买的商品订单号（每次不一样） 20180301073422891
        total_amount=float(100.00),  # 交易金额(单位: 元 保留俩位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
    return jsonify({'code': 200, 'url': pay_url})
    # 支付，返回支付url


import datetime, time


@user_blue.route("/callback")
def callback():
    # 接收参数，
    data = request.args
    datames = {k: v for k, v in data.items()}
    # 删除字典中key为sign的记录
    sign = datames.pop('sign')
    # 鉴权 订单号 流水号
    pay = get_ali_object()
    flag = pay.verify(datames, sign)

    if flag == True:
        # 支付宝流水号
        transaction_no = datames['trade_no']
        # 订单号
        order_no = datames['out_trade_no']
        # 订单号更新订单表
        try:

            record = VipRecord.query.filter(VipRecord.order_no == order_no).first()
            record.status = 2
            record.transaction_no = transaction_no
            db.session.add(record)
            # 更新用户表
            User.query.filter(User.id == record.userid).update({"level": 2})
            # # 更新vip表
            vip = Vip.query.filter(Vip.userid == record.userid, Vip.status == 1).first()
            if vip is not None:
                # 结束时间+购买年限
                etime = vip.e_time.split("-")
                tyear = int(etime[0]) + int(record.year)
                yearstr = "-"
                etime[0] = str(tyear)
                retime = yearstr.join(etime)
                vip.e_time = retime
                db.session.add(vip)
            else:
                nowyear = datetime.date.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%m:%s")
                etime = nowyear.split("-")
                tyear = int(etime[0]) + int(record.year)
                etime[0] = str(tyear)
                yearstr = "-"
                retime = yearstr.join(etime)
                vip = Vip(userid=record.userid, s_time=datetime.datetime.now(), e_time=retime)
                db.session.add(vip)
            db.session.commit()
        except:
            db.session.rollback()
    else:
        print("鉴权失败")
    return 'ok'


# 添加课程使用.获取标签,分类,类别
@user_blue.route('/getTags')
def getTags():
    tags = Tags.query.all()
    tagslist = [{'id': i.id, 'name': i.name} for i in tags]
    types = Ctype.query.all()
    typeslist = [{'id': i.id, 'name': i.name} for i in types]
    ctype = CourseType.query.all()
    clist = [{'id': i.id, 'name': i.name} for i in ctype]
    return jsonify({'code': 200, 'tags': tagslist, 'types': typeslist, 'clist': clist})


from qiniu import Auth


@user_blue.route('/get_qntoken')
def get_qntoken():
    # 需要填写你的 Access Key 和 Secret Key
    access_key = 'Kw2x1zJZ0R_7C4MmTfnGNyBdPcj-fkHOhNsMLMNG'
    secret_key = 'NP6jsirMliBo-p_rvci4oTAGK0UApcfViHyHNbQH'

    # 构建鉴权对象
    q = Auth(access_key, secret_key)

    # 要上传的空间
    bucket_name = '2205aaaa'
    # 3600为token过期时间，秒为单位。3600等于一小时
    token = q.upload_token(bucket_name)

    print(token)

    return jsonify({'code': 200, "token": token})


# 添加课程
@user_blue.route('/addCourse',methods=['POST'])
def addCourse():
    try:
      #获取参数
      data = json.loads(request.data)
      #写入课程表
      course = Course(name = data['name'],url=data['url'],descrip=data['desc'],ctype= data['type'])

      db.session.add(course)
      #获取新加的课程的id
      scourse = Course.query.filter(Course.name ==data['name']).first()
      #写入课程标签表
      for i in data['tags']:
          sql = "insert into course_tag(courseid, tagid) values (%d,%d)"%(scourse.id,int(i))
          db.session.execute(sql)
      #课程分类表
      for i in data['ctype']:
          sql = "insert into course_cate(courseid, course_typeid) values (%d,%d)"%(scourse.id,int(i))
          db.session.execute(sql)
      db.session.commit()
      # return 'ok'
    except:
        db.session.rollback()
    return jsonify({'code':200})


@user_blue.route('/addCourse',methods=['POST'])
def addCours():
    try:
        # 获取参数
        data = json.loads(request.data)
        # 写入课程表
        course = Course(name=data['name'],url=data['url'],descrip=data['desc'],ctype=data['type'])
        db.session.add(course)
        # 获取新加的课程id
        scourse = Course.query.filter_by(name = data['name']).first()
        # 写入课程标签表
        for i in data['tags']:
            sql = "insert into course_tag(courseid,tagid) values(%d,%d)"%(int(scourse.id),int(i))
            db.session.execute(sql)
        # 写入课程分类表
        for i in str(data['ctype']):
            sql = "insert into course_cate(courseid,course_typeid) values(%d,%d)"%(int(scourse.id),int(i))
            db.session.execute(sql)
        db.session.commit()
    except:
        db.session.rollback()
    return jsonify({'code':200})

import math

@user_blue.route('/getCourse')
def getCourse():
    #获取参数page
    page = int(request.args.get('page'))
    #获取上线、即将上线条件
    online = int(request.args.get('is_publish'))
    #查询总条数
    total = Course.query.filter(Course.is_publish==online).count()
    #定义每页显示多少条
    page_size=2
    #查询当前页记录
    start =math.ceil((page-1)*page_size)
    #获取排序字段
    orderpara = request.args.get('orderpara')
    if orderpara == 'new':
        course = Course.query.order_by(Course.create_time.desc()).filter(Course.is_publish==online).offset(start).limit(page_size).all()
    else:
        course = Course.query.order_by(Course.views.desc()).filter(Course.is_publish == online).offset(start).limit(page_size).all()
    list = [{"id":i.id,"name":i.name,"url":i.url,'views':i.views}for i in course]
    #返回结果
    return jsonify({'code':200,"clist":list,"total":total,'page_size':page_size})

